using System.Collections;
using System.Collections.Generic;
using Game.Core;
using UnityEngine;

namespace Game.Manager
{
	public class ResourceManager : Singleton<ResourceManager>
	{
		private Dictionary<string, Object> commonResources;

		private Dictionary<string, Object> resources;

		private Dictionary<string, Sprite> sprites = new Dictionary<string, Sprite>();

		private Dictionary<string, AudioClip> audios = new Dictionary<string, AudioClip>();

		private List<string> loaders;

		public ResourceManager()
		{
			commonResources = new Dictionary<string, Object>();
			resources = new Dictionary<string, Object>();
			loaders = new List<string>();
		}

		public void LoadCommonResource(string path)
		{
			if (commonResources.ContainsKey(path))
			{
				Fire(new BaseEvent("game.resource_loaded", path));
			}
			else if (!loaders.Contains(path))
			{
				Client.Instance.StartCoroutine(StartLoadCommonResource(path));
			}
		}

		private IEnumerator StartLoadCommonResource(string path)
		{
			WWW www = new WWW(GetPath(path));
			yield return www;
			AssetBundle data = www.assetBundle;
			if (commonResources.ContainsKey(path))
			{
				commonResources[path] = data.mainAsset;
			}
			else
			{
				commonResources.Add(path, data.mainAsset);
			}
			if (loaders.Contains(path))
			{
				loaders.Remove(path);
			}
			www.Dispose();
			Fire(new BaseEvent("game.resource_loaded", path));
		}

		public void LoadSprite(string path)
		{
			if (resources.ContainsKey(path))
			{
				Fire(new BaseEvent("game.resource_loaded", path));
			}
			else if (!loaders.Contains(path))
			{
				Client.Instance.StartCoroutine(StartLoadSprite(path));
			}
		}

		private IEnumerator StartLoadSprite(string path)
		{
			WWW www = new WWW(GetPath(path));
			yield return www;
			AssetBundle data = www.assetBundle;
			Object[] spriteRes = data.LoadAllAssets(typeof(Sprite));
			int length = spriteRes.Length;
			for (int i = 0; i < length; i++)
			{
				Sprite tempSprite = spriteRes[i] as Sprite;
				sprites.Add(tempSprite.name, tempSprite);
			}
			if (loaders.Contains(path))
			{
				loaders.Remove(path);
			}
			data.Unload(false);
			www.Dispose();
			Fire(new BaseEvent("game.resource_loaded", path));
		}

		public int GetSpritesCount()
		{
			return sprites.Count;
		}

		public Sprite GetSprite(string name)
		{
			return sprites[name];
		}

		public void LoadAudio(string path)
		{
			if (resources.ContainsKey(path))
			{
				Fire(new BaseEvent("game.resource_loaded", path));
			}
			else if (!loaders.Contains(path))
			{
				Client.Instance.StartCoroutine(StartLoadAudio(path));
			}
		}

		private IEnumerator StartLoadAudio(string path)
		{
			WWW www = new WWW(GetPath(path));
			yield return www;
			AssetBundle data = www.assetBundle;
			if (audios.ContainsKey(path))
			{
				audios[path] = data.mainAsset as AudioClip;
			}
			else
			{
				audios.Add(path, data.mainAsset as AudioClip);
			}
			if (loaders.Contains(path))
			{
				loaders.Remove(path);
			}
			data.Unload(false);
			www.Dispose();
			Fire(new BaseEvent("game.resource_loaded", path));
		}

		public int GetAudiosCount()
		{
			return audios.Count;
		}

		public AudioClip GetAudio(string name)
		{
			return audios[name];
		}

		public Object GetResource(string path)
		{
			if (resources.ContainsKey(path))
			{
				return resources[path];
			}
			return null;
		}

		public void LoadResource(string path)
		{
			if (resources.ContainsKey(path))
			{
				Fire(new BaseEvent("game.resource_loaded", path));
			}
			else if (!loaders.Contains(path))
			{
				Client.Instance.StartCoroutine(StartLoadResource(path));
			}
		}

		private IEnumerator StartLoadResource(string path)
		{
			WWW www = new WWW(GetPath(path));
			yield return www;
			AssetBundle data = www.assetBundle;
			if (resources.ContainsKey(path))
			{
				resources[path] = data.mainAsset;
			}
			else
			{
				resources.Add(path, data.mainAsset);
			}
			if (loaders.Contains(path))
			{
				loaders.Remove(path);
			}
			data.Unload(false);
			www.Dispose();
			Fire(new BaseEvent("game.resource_loaded", path));
		}

		public void LoadAndPushPool(string path, int preloadAmount, int limitAmount, int cullAbove, int cullMaxPerPass)
		{
			if (resources.ContainsKey(path))
			{
				Fire(new BaseEvent("game.resource_loaded", path));
			}
			else
			{
				Client.Instance.StartCoroutine(StartLoadAndPushPool(path, preloadAmount, limitAmount, cullAbove, cullMaxPerPass));
			}
		}

		private IEnumerator StartLoadAndPushPool(string path, int preloadAmount, int limitAmount, int cullAbove, int cullMaxPerPass)
		{
			WWW www = new WWW(GetPath(path));
			yield return www;
			AssetBundle data = www.assetBundle;
			if (resources.ContainsKey(path))
			{
				resources[path] = data.mainAsset as GameObject;
			}
			else
			{
				resources.Add(path, data.mainAsset as GameObject);
			}
			GameObject obj = data.mainAsset as GameObject;
			Singleton<GamePoolManager>.Instance.InitPrefabPool(path, obj.transform, preloadAmount, limitAmount, cullAbove, cullMaxPerPass);
			if (loaders.Contains(path))
			{
				loaders.Remove(path);
			}
			data.Unload(false);
			www.Dispose();
			Fire(new BaseEvent("game.resource_loaded", path));
		}

		public string GetPath(string path)
		{
			return string.Empty;
		}

		public void UnloadResource(string path)
		{
			if (resources.ContainsKey(path))
			{
				resources.Remove(path);
			}
		}

		public void AddCallBack(EventObjectHandler handler)
		{
			Bind("game.resource_loaded", handler);
		}

		public void RemoveCallBack(EventObjectHandler handler)
		{
			UnBind("game.resource_loaded", handler);
		}
	}
}
